﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using ECommon.InModel;

namespace ECommon
{
    /// <summary>
    /// 文件日志工具
    /// </summary>
    public static partial class FileLogTool
    {
        /// <summary>
        /// Trace输出
        /// </summary>
        /// <param name="ex">Trace异常</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task TraceAsync(Exception ex, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (ex == null) { return; }
            string invokeStr = ex.TargetSite == null ? "空" : ex.TargetSite.Name;
            string detailStr = ex.InnerException == null ? "空" : ex.InnerException.Message;
            await WriteLogAsync(LogLevel.Trace, ex.Message, ex.StackTrace, ex.Source, invokeStr, detailStr, logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Trace输出
        /// </summary>
        /// <param name="msg">Trace消息</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task TraceAsync(string msg, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (string.IsNullOrEmpty(msg)) { return; }
            string source = "空";
            string invoke = "空";
            string trace = GetLogTraceInfo(0, out source, out invoke);
            trace = trace == null || string.IsNullOrEmpty(trace.Trim()) ? "空" : trace.Trim();
            await WriteLogAsync(LogLevel.Trace, msg, trace, source, invoke, "空", logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Debug输出
        /// </summary>
        /// <param name="ex">Debug异常</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task DebugAsync(Exception ex, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (ex == null) { return; }
            string invokeStr = ex.TargetSite == null ? "空" : ex.TargetSite.Name;
            string detailStr = ex.InnerException == null ? "空" : ex.InnerException.Message;
            await WriteLogAsync(LogLevel.Debug, ex.Message, ex.StackTrace, ex.Source, invokeStr, detailStr, logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Debug输出
        /// </summary>
        /// <param name="msg">Debug消息</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task DebugAsync(string msg, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (string.IsNullOrEmpty(msg)) { return; }
            string source = "空";
            string invoke = "空";
            string trace = GetLogTraceInfo(0, out source, out invoke);
            trace = trace == null || string.IsNullOrEmpty(trace.Trim()) ? "空" : trace.Trim();
            await WriteLogAsync(LogLevel.Debug, msg, trace, source, invoke, "空", logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Info输出
        /// </summary>
        /// <param name="ex">Info异常</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task InfoAsync(Exception ex, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (ex == null) { return; }
            string invokeStr = ex.TargetSite == null ? "空" : ex.TargetSite.Name;
            string detailStr = ex.InnerException == null ? "空" : ex.InnerException.Message;
            await WriteLogAsync(LogLevel.Info, ex.Message, ex.StackTrace, ex.Source, invokeStr, detailStr, logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Info输出
        /// </summary>
        /// <param name="msg">Info消息</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task InfoAsync(string msg, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (string.IsNullOrEmpty(msg)) { return; }
            string source = "空";
            string invoke = "空";
            string trace = GetLogTraceInfo(0, out source, out invoke);
            trace = trace == null || string.IsNullOrEmpty(trace.Trim()) ? "空" : trace.Trim();
            await WriteLogAsync(LogLevel.Info, msg, trace, source, invoke, "空", logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Warning输出
        /// </summary>
        /// <param name="ex">Warning异常</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task WarningAsync(Exception ex, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (ex == null) { return; }
            string invokeStr = ex.TargetSite == null ? "空" : ex.TargetSite.Name;
            string detailStr = ex.InnerException == null ? "空" : ex.InnerException.Message;
            await WriteLogAsync(LogLevel.Warning, ex.Message, ex.StackTrace, ex.Source, invokeStr, detailStr, logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Warning输出
        /// </summary>
        /// <param name="msg">Warning消息</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task WarningAsync(string msg, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (string.IsNullOrEmpty(msg)) { return; }
            string source = "空";
            string invoke = "空";
            string trace = GetLogTraceInfo(0, out source, out invoke);
            trace = trace == null || string.IsNullOrEmpty(trace.Trim()) ? "空" : trace.Trim();
            await WriteLogAsync(LogLevel.Warning, msg, trace, source, invoke, "空", logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Error输出
        /// </summary>
        /// <param name="ex">Error异常</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task ErrorAsync(Exception ex, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (ex == null) { return; }
            string invokeStr = ex.TargetSite == null ? "空" : ex.TargetSite.Name;
            string detailStr = ex.InnerException == null ? "空" : ex.InnerException.Message;
            await WriteLogAsync(LogLevel.Error, ex.Message, ex.StackTrace, ex.Source, invokeStr, detailStr, logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Error输出
        /// </summary>
        /// <param name="msg">Error消息</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task ErrorAsync(string msg, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (string.IsNullOrEmpty(msg)) { return; }
            string source = "空";
            string invoke = "空";
            string trace = GetLogTraceInfo(0, out source, out invoke);
            trace = trace == null || string.IsNullOrEmpty(trace.Trim()) ? "空" : trace.Trim();
            await WriteLogAsync(LogLevel.Error, msg, trace, source, invoke, "空", logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Fatal输出
        /// </summary>
        /// <param name="ex">Fatal异常</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task FatalAsync(Exception ex, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (ex == null) { return; }
            string invokeStr = ex.TargetSite == null ? "空" : ex.TargetSite.Name;
            string detailStr = ex.InnerException == null ? "空" : ex.InnerException.Message;
            await WriteLogAsync(LogLevel.Fatal, ex.Message, ex.StackTrace, ex.Source, invokeStr, detailStr, logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// Fatal输出
        /// </summary>
        /// <param name="msg">Fatal消息</param>
        /// <param name="logDirOrPath">绝对的日志目录或路径</param>
        /// <param name="logConfigFilePath">日志配置文件的绝对路径</param>
        public static async Task FatalAsync(string msg, string logDirOrPath = null, string logConfigFilePath = null)
        {
            if (string.IsNullOrEmpty(msg)) { return; }
            string source = "空";
            string invoke = "空";
            string trace = GetLogTraceInfo(0, out source, out invoke);
            trace = trace == null || string.IsNullOrEmpty(trace.Trim()) ? "空" : trace.Trim();
            await WriteLogAsync(LogLevel.Fatal, msg, trace, source, invoke, "空", logDirOrPath, logConfigFilePath);
        }

        /// <summary>
        /// 写入日志
        /// </summary>
        /// <param name="logLevel">日志级别</param>
        /// <param name="msg">消息</param>
        /// <param name="traceStr">追溯</param>
        /// <param name="sourceStr">来源</param>
        /// <param name="invokeStr">调用</param>
        /// <param name="detailStr">详细</param>
        /// <param name="logConfigFilePath">日志路径</param>
        /// <returns>任务</returns>
        private static async Task WriteLogAsync(LogLevel logLevel, string msg, string traceStr, string sourceStr, string invokeStr, string detailStr, string logDirOrPath = null, string logConfigFilePath = null)
        {
            await Task.Run(() =>
            {
                WriteLog(logLevel, msg, traceStr, sourceStr, invokeStr, detailStr, logDirOrPath, logConfigFilePath);
            });
        }
    }
}
